/*msgrcv.c 接收指定类型消息的程序，头文件详细信息见上一个文件 */
#include "msgexamp.h"

int main(int argc, char **argv) {
    int msgid; // 消息队列的标识符
    int type;  // 要接收的消息类型
    // 动态分配内存，用于存储接收到的消息
    struct my_msg_st *my_data = (struct my_msg_st *)malloc(sizeof(struct my_msg_st));

    // 检查命令行参数是否足够
    if (argc < 2) {
        printf("USAGE msgexample msgtype\n");
        return -1;
    }

    // 将命令行参数转换为整数，作为要接收的消息类型
    type = atoi(argv[1]);

    // 检查消息类型是否合法
    if (type < 0 || type > 3) {
        printf("msgtype should be one of 1,2,3");
        return -1;
    }

    // 获取消息队列的标识符，如果消息队列不存在则创建
    msgid = msgget((key_t)MSG_KEY, IPC_CREAT | S_IRUSR | S_IWUSR);
    if (msgid == -1) {
        perror("get message queue failed ");
        return -1;
    }

    // 进入循环，不断尝试从消息队列中接收指定类型的消息
    while (1) {
        // 尝试从消息队列中接收指定类型的消息，使用 IPC_NOWAIT 标志表示非阻塞模式
        if (msgrcv(msgid, (void *)my_data, sizeof(struct my_msg_st), (long)type, IPC_NOWAIT) != -1) {
            // 打印接收到的消息类型
            printf("The message type is:%ld\n", my_data->my_msg_type);
            // 打印接收到的消息内容
            printf("The message content is:%s\n", my_data->text);
        }
        // 如果没有匹配类型的消息，跳出循环
        else if (ENOMSG == errno) {
            printf("there is no any message which is matched to message type \n");
            break;
        }
    }

    // 释放动态分配的内存
    free(my_data);

    return 0;
}